作者:粉笔画1995_996 | 来源:互联网 | 2023-09-25 00:52
篇首语:本文由编程笔记#小编为大家整理,主要介绍了5-5 决策树的剪枝算法相关的知识,希望对你有一定的参考价值。
树的剪枝算法
输入:
ID3或C4.5的决策树
参数a
输出:
剪枝后的决策树
T
a
T_a
Ta
递归版本
- 从树的根结点开始
- 如果该结点的孩子中存在子树(不全是叶子结点),则先对子树做prune
- 所有子树都prune之后,再判断该结点的孩子是否都是叶子
- 如果不全是叶子,对该结点的算法结束
- 如果该结点的孩子都是叶子,则尝试对该结点剪枝
5.a 计算
C
a
(
T
B
)
C_a(T_B)
Ca(TB),代表该结点split后以该结点为根结点的子树的损失,其损失的计算方式与整棵树的计算方式相同
C
a
(
T
B
)
=
∑
∣
T
∣
N
t
H
t
(
T
)
+
a
∣
T
∣
C_a(T_B) = \\sum^|T|N_tH_t(T) + a|T|
Ca(TB)=∑∣T∣NtHt(T)+a∣T∣
因此在生成树的时候为每个叶子结点保存它的
N
t
N_t
Nt和
H
t
H_t
Ht
5.b 计算
C
a
(
T
A
)
C_a(T_A)
Ca(TA),代表该结点split之前作为一个叶子结点时的熵。因此在生成树时记录该split之前的熵
5.c 比较
C
a
(
T
B
)
C_a(T_B)
Ca(TB)和
C
a
(
T
A
)
C_a(T_A)
Ca(TA),如果
C
a
(
T
A
)
≤
C
a
(
T
B
)
C_a(T_A)\\le C_a(T_B)
Ca(TA)≤Ca(TB),则将该结点修改为叶子结点。即:计算该结点的输出标记,并删除它的所有孩子结点。 - 对该结点的处理结束,由于这个算法是递归调用的,如果该结点有父结点,则要继续处理它的父结点。
def isTree(Node):
return 'child' in Node.keys()
def Clip(Node):
bestNt = 0
for value in Node['child']:
if Node['child'][value]['Nt'] > bestNt:
bestNt = Node['child'][value]['Nt']
bestLabel = Node['child'][value]['label']
Node['label'] = bestLabel
Node.pop('child')
def Merge(Node, alpha):
CT_b = 0
for value in Node['child']:
CT_b = CT_b + Node['child'][value]['Nt'] * Node['child'][value]['entropy'] + alpha
CT_a = Node['entropy'] + alpha
if CT_a <&#61; CT_b:
Clip(Node)
def prune(Node, alpha):
for value in Node[&#39;child&#39;]:
if isTree(Node[&#39;child&#39;][value]):
prune(Node[&#39;child&#39;][value], alpha)
isAllLeaf &#61; True
for value in Node[&#39;child&#39;]:
if isTree(Node[&#39;child&#39;][value]):
isAllLeaf &#61; False
break
if isAllLeaf:
Merge(Node, alpha)
DP版本
【&#xff1f;】如何通过DP实现